<template>
  <div>
    <Dialog :show="dialogConfig.show" :title="dialogConfig.title" :buttons="dialogConfig.buttons" width="600px"
      :showCancel="showCancel" @close="dialogConfig.show = false">
      <el-form :model="formData" :rules="rules" ref="formDataRef" label-width="100px" @submit.prevent>
        <el-form-item label="文件"> {{ formData.fileName }} </el-form-item>
        <template v-if="showType == 0">
          <el-form-item label="有效期" prop="validType">
            <el-radio-group v-model="formData.validType">
              <el-radio :label="0">1天</el-radio>
              <el-radio :label="1">7天</el-radio>
              <el-radio :label="2">30天</el-radio>
              <el-radio :label="3">永久有效</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="提取码" prop="codeType">
            <el-radio-group v-model="formData.codeType">
              <el-radio :label="0">自定义</el-radio>
              <el-radio :label="1">系统生成</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item prop="code" v-if="formData.codeType == 0">
            <el-input clearable placeholder="请输入5位提取码" v-model.trim="formData.code" maxLength="5"
              :style="{ width: '130px' }"></el-input>
          </el-form-item>
          <el-form-item label="选择用户">
            <el-checkbox-group v-model="selectedUserIds">
              <el-checkbox v-for="user in userList" :key="user.userId" :label="user.userId">
                <img :src="user.qqAvatar || (proxy.globalInfo.avatarUrl + user.userId)"
                  style="width:24px;height:24px;border-radius:50%;margin-right:8px;" />
                {{ user.nickName }} ({{ user.email }})
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </template>
        <template v-else>
          <el-form-item label="分享连接" prop="validType">
            {{ shareUrl }}{{ resultInfo.shareId }}
          </el-form-item>
          <el-form-item label="提取码" prop="validType">
            {{ resultInfo.code }}
          </el-form-item>
          <el-form-item prop="validType">
            <el-button type="primary" @click="copy">复制链接极提取码</el-button>
          </el-form-item>
        </template>
      </el-form>
    </Dialog>
  </div>
</template>

<script setup>
import useClipboard from "vue-clipboard3";
const { toClipboard } = useClipboard();
import { ref, getCurrentInstance, nextTick, onMounted } from "vue";
import { useRouter } from "vue-router";

const $ = window.jQuery;
const QssSdk = window.QssSdk;
const sm4 = window.sm4;

const { proxy } = getCurrentInstance();
const router = useRouter();

const shareUrl = ref(document.location.origin + "/share/");

const api = {
  shareFile: "/share/shareFile",
};
const showType = ref(0);
const formData = ref({});
const formDataRef = ref();
const rules = {
  validType: [{ required: true, message: "请选择有效期" }],
  codeType: [{ required: true, message: "请选择提取码类型" }],
  code: [
    { required: true, message: "请输入提取码" },
    { validator: proxy.Verify.shareCode, message: "提取码只能是数字字母" },
    { min: 5, message: "提取码最少5位" },
  ],
};

const showCancel = ref(true);
const dialogConfig = ref({
  show: false,
  title: "分享",
  buttons: [
    {
      type: "primary",
      text: "确定",
      click: (e) => {
        share();
      },
    },
  ],
});

const resultInfo = ref({});
const userList = ref([]);
const selectedUserIds = ref([]);

const loadUserList = async () => {
  let result = await proxy.Request({
    url: "/admin/loadUserList",
    params: { pageNo: 1, pageSize: 1000 },
  });
  if (result && result.data && result.data.list) {
    userList.value = result.data.list;
  }
};
onMounted(loadUserList);

function getPhoneFromCookie() {
  // 获取名为 userInfo 的 cookie
  const match = document.cookie.match(new RegExp('(^| )userInfo=([^;]+)'));
  if (match) {
    // 解码并解析 JSON
    const userInfo = JSON.parse(decodeURIComponent(match[2]));
    return userInfo.phone;
  }
  return '';
}
// console.log("getPhoneFromCookie:", getPhoneFromCookie());

function stringToUint8Array(str) {
  const encoder = new TextEncoder();
  return encoder.encode(str);
}

function Uint8ArrayToString(byteArray) {
  const decoder = new TextDecoder();
  return decoder.decode(byteArray);
}

//解密mackey，实际生产环境由后台服务解密并返回
function decryptMacKey(orgKey, macKey) {
  let macKeyAndCheck = QssSdk.hex2u8ab(macKey);
  let mackey = macKeyAndCheck.slice(0, 16);
  let macchk = macKeyAndCheck.slice(16);
  let orgMacKey = sm4.decrypt(mackey, orgKey, {
    padding: 'none',
    mode: 'ecb',
    output: 'array'
  });
  let hexMacKey = QssSdk.ab2hex(orgMacKey);
  console.log('解密MacKey:', hexMacKey);
  let data = new Uint8Array(16).fill(0x00);
  let check = QssSdk.calcHMac(hexMacKey, data).slice(0, 8);
  if (check.toString() == macchk.toString()) {
    QssSdk.setOrgMacKey(hexMacKey);
    return true;
  } else {
    showLog("mackey校验失败");
  }
  return false;
};


const share = async () => {
  if (Object.keys(resultInfo.value).length > 0) {
    dialogConfig.value.show = false;
    return;
  }
  formDataRef.value.validate(async (valid) => {
    if (!valid) {
      return;
    }
    let params = {};

    // 获取随机数和鉴权
    let random = "";

    // Wrap QSS SDK operations in Promises
    try {
      // Get random number
      const randomPromise = new Promise((resolve, reject) => {
        QssSdk.getRandom(16, function (code, data) {
          if (code === QssSdk.ErrCode.STATUS_OK) {
            resolve(data);
          } else {
            reject(new Error('Failed to get random number'));
          }
        });
      });
      random = await randomPromise;

      // Apply authentication
      const orgCode = "3401043927530314";
      const orgKey = "8C0F01FA42ACF6FD0B58373934E42F6F";

      if (!orgCode || !orgKey) {
        throw new Error("机构应用代码或密钥不能为空");
      }

      let randomAb = QssSdk.hex2u8ab(random);
      let challenge = sm4.encrypt(randomAb, orgKey, {
        padding: 'none',
        mode: 'ecb'
      });

      const authPromise = new Promise((resolve, reject) => {
        const myOptions = {
          orgCode: orgCode,
          challenge: challenge,
          appName: "CtqKmsPriApp",
          appID: "zdxlz_demo",
          account: getPhoneFromCookie(),
        };

        QssSdk.initAuth(myOptions, function (code, data) {
          if (code === QssSdk.ErrCode.STATUS_OK) {
            if (decryptMacKey(orgKey, data.macKey)) {
              $("#KeyHandleSelect").empty();
              $("#KeyHandleSelect").prepend("<option value='0'>选择密钥句柄</option>");
              resolve(data);
            } else {
              reject(new Error('MacKey validation failed'));
            }
          } else {
            reject(new Error('Authentication failed'));
          }
        });
      });

      await authPromise;

      // 根据 shareUserIds 查找手机号
      let receiverInfo = userList.value
        .filter(user => selectedUserIds.value.includes(user.userId))
        .map(user => user.phone)
        .join(',');
      console.log("receiverInfo:", receiverInfo);
      let keyIds = [];

      // Create session key
      const sessionId = Date.now().toString();
      const sessionKeyPromise = new Promise((resolve, reject) => {
        QssSdk.createSessionKey(receiverInfo, sessionId, function (code, data) {
          console.log("data:", data);
          keyIds = data.keyId;

          if (code === QssSdk.ErrCode.STATUS_OK) {
            resolve(data);
          } else {
            reject(new Error('Failed to create session key'));
          }
        });
      });

      const sessionData = await sessionKeyPromise;
      const sessionKeyHandle = sessionData.sessionKeyHandle;
      console.log("sessionKeyHandle:", sessionKeyHandle);
      console.log("会话秘钥:", sessionData.sessionKeyHandle);


      // 向后端拉取文件
      let fileInfo = await proxy.Request({
        url: `/file/getFile/${formData.value.fileId}`,
      });
      console.log("文件信息:", fileInfo);
      // console.log("fileStream:",fileInfo.data.fileInfo);


      if (sessionKeyHandle == "0") {
        console.log("请选择密钥句柄！！！");
        return;
      }
      // console.log("fileInfo.data.fileStream:",fileInfo.data.fileStream);
      let plainText = fileInfo.data.fileStream;
      if (plainText == "" || plainText == null) {
        console.log("待加解密数据不能为空！！！");
        return;
      }
      // 字符串 -> 8位无符号整形(0-255) 数组
      let plainData = stringToUint8Array(plainText);
      console.log("plainData:", plainData);
      // 16进制字符串
      //  console.log(QssSdk.ab2hex(plainData));
      //1025:SGD_SM4_ECB(默认) ，1026:SGD_SM4_CBC
      const encryptedData = await new Promise((resolve, reject) => {
        QssSdk.qcEncrypt(sessionKeyHandle, 1025, 1, null, plainData, function (code, data) {
          console.log("===================== qcEncrypt =====================");
          console.log('code:{0}', code);
          if (code == QssSdk.ErrCode.STATUS_OK) {
            console.log("加密数据成功");
            let hexData = QssSdk.ab2hex(data);
            resolve(hexData);
          } else {
            reject(new Error("加密数据失败"));
          }
        });
      });

      // 将加密后的数据赋值给params.fileStream
      params.filestream = encryptedData;
      params.keyIds = keyIds;

      if (fileInfo && fileInfo.data) {
        params.fileName = fileInfo.data.fileName;
      }

      Object.assign(params, formData.value);
      params.shareUserIds = selectedUserIds.value;
      let result = await proxy.Request({
        url: api.shareFile,
        params: params,
      });
      if (!result) {
        return;
      }
      showType.value = 1;
      resultInfo.value = result.data;
      dialogConfig.value.buttons[0].text = "确定";
      showCancel.value = false;

    } catch (error) {
      console.error('Error during share process:', error);
      proxy.Message.error("分享过程出错：" + error.message);
    }
  });
};

const show = (data) => {
  showCancel.value = true;
  dialogConfig.value.show = true;
  showType.value = 0;
  resultInfo.value = {};
  nextTick(() => {
    formDataRef.value.resetFields();
    formData.value = Object.assign({}, data);
  });
};

defineExpose({ show });

const copy = async () => {
  await toClipboard(
    `链接:${shareUrl.value}${resultInfo.value.shareId} 提取码: ${resultInfo.value.code}`
  );
  proxy.Message.success("复制成功");
};
</script>

<style lang="scss" scoped></style>
